package com.beeasy.hzbpm.ctrl;

import cn.hutool.core.util.IdUtil;
import com.beeasy.hzbpm.filter.Auth;
import com.github.llyb120.json.Arr;
import com.github.llyb120.json.Obj;
import com.github.llyb120.nami.ctrl.Ctrl;
import com.mongodb.client.model.UpdateOptions;
import org.bson.Document;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.beeasy.hzbpm.bean.MongoService.db;
import static com.github.llyb120.json.Json.*;

public class article extends Ctrl {

    public boolean save() {
        $request.ss("id", IdUtil.objectId());
        if ($request.s("warehouseType").equals("2")) {
            int number = Integer.parseInt($request.s("number"));
            Obj item = ro(db.getCollection("article")
                    .find(bo(
                            "id", $request.ss("wupinId")
                    ))
                    .projection(bo("_id", 0))
                    .first());
            int inStockNumber = item.i("inStockNumber", 0);
            int Warehouse = item.i("WarehouseNumber", 0);
            db.getCollection("article")
                    .updateOne(
                            bo("id", $request.s("wupinId")),
                            bo("$set",
                                    o("inStockNumber", inStockNumber - number, "WarehouseNumber", Warehouse + number)
                            )
                    );
            $request.put("lastModify", new Date());
            $request.put("uids", Auth.getUid());
            db.getCollection("article")
                    .replaceOne(bo("id", $request.ss("id")), booo($request), new UpdateOptions().upsert(true));
        } else {
            $request.put("lastModify", new Date());
            $request.put("uids", Auth.getUid());
            $request.remove("_id");
            db.getCollection("article")
                    .replaceOne(bo("id", $request.ss("id")), booo($request), new UpdateOptions().upsert(true));
        }
        return true;
    }

    /**
     * 修改库存
     */
    public boolean updateWarehouse() {
        if (null != $request.s("type")) {
            db.getCollection("article")
                    .updateOne(
                            bo("id", $request.s("id")),
                            bo("$set",
                                    o($request)
                            )
                    );
        } else {
            db.getCollection("article")
                    .updateOne(
                            bo("id", $request.s("id")),
                            bo("$set",
                                    o($request),
                                    "$push", o(
                                            "warehouseList", o(
                                                    $request,
                                                    "updataTime", new Date()
                                            )
                                    )
                            )
                    );
        }

        return true;
    }

    /**
     * 修改申请状态
     */
    public boolean updateclaim() {
        db.getCollection("article")
                .updateOne(
                        bo("id", $request.s("id")),
                        bo("$set",
                                o("status", $request.ss("status"))
                        )
                );
        if ($request.ss("status").equals("claimNo")) return true;
        int number = Integer.parseInt($request.s("number"));
        Obj item = ro(db.getCollection("article")
                .find(bo(
                        "id", $request.ss("wupinId")
                ))
                .projection(bo("_id", 0))
                .first());
        int inStockNumber = item.i("inStockNumber", 0);
        int Warehouse = item.i("WarehouseNumber", 0);
        db.getCollection("article")
                .updateOne(
                        bo("id", $request.s("wupinId")),
                        bo("$set",
                                o("inStockNumber", inStockNumber - number, "WarehouseNumber", Warehouse + number)
                        )
                );

        $request.put("uids", Auth.getUid());
        $request.put("id", IdUtil.objectId());
        $request.put("lastModify", new Date());
        $request.put("warehouseType", "2");
        $request.remove("_id");
        db.getCollection("article").insertOne(booo($request));
        return true;
    }


    public Object list() {
        int count = 0;
        Arr<Document> list = null;
        if (null != $request.ss("warehouseType") && $request.ss("warehouseType").equals("claim")) {
            if ($request.ss("uids").equals("1")) {
                count = (int) db.getCollection("article").countDocuments(bo("warehouseType", $request.ss("warehouseType")));
                list = db.getCollection("article").find(bo("warehouseType", $request.ss("warehouseType")))
                        .projection(bo(
//                        "_id", 0
                        ))
                        .sort(bo(
                                "lastModify", -1
                        ))
                        .into(a());
            } else {
                count = (int) db.getCollection("article").countDocuments(bo("warehouseType", $request.ss("warehouseType")));
                list = db.getCollection("article").find(bo("warehouseType", $request.ss("warehouseType"), "uids", $request.ss("uids")))
                        .projection(bo(
//                        "_id", 0
                        ))
                        .sort(bo(
                                "lastModify", -1
                        ))
                        .into(a());
            }
        } else {
            count = (int) db.getCollection("article").countDocuments(bo($request));
            list = db.getCollection("article").find(bo($request))
                    .projection(bo(
//                        "_id", 0
                    ))
                    .sort(bo(
                            "lastModify", -1
                    ))
                    .into(a());
        }

        return o(
                "list", list,
                "total", count
        );
    }

    public Object total() {
        Arr<Document> list = db.getCollection("article").find(bo("warehouseType", "1"))
                .projection(bo())
                .sort(bo("lastModify", -1))
                .into(a());
        Arr<Document> arr = new Arr<>();
        try {
            for (int i = 0; i < list.size(); i++) {
                Map map = list.get(i);
                //总的出库数量
                Double WarehouseNumber = null != map.get("WarehouseNumber") ? Double.parseDouble(map.get("WarehouseNumber").toString()) : 0;
                List list1 = (List) map.get("warehouseList");
                Map<String, Object> setMap = new HashMap();
                if (null == list1) continue;
                for (int j = 0; j < list1.size(); j++) {
                    Map<String, Object> map1 = (Map) list1.get(j);
                    map1.put("category", map.get("category"));
                    map1.put("name", map.get("name"));
                    //同一价格
                    if (null != setMap.get(String.valueOf(map1.get("price")))) {
                        Map chongfuMap = (Map) setMap.get(String.valueOf(map1.get("price")));
                        String op = chongfuMap.get("formInStockNumber").toString();
                        double d = Double.parseDouble(op);
                        String mapOp1 = map1.get("formInStockNumber").toString();
                        double mapOp1Double = Double.parseDouble(mapOp1);
                        map1.put("formInStockNumber", mapOp1Double + d);
                        //同一价格下应该把现有库存相加减去出库数量
                        if (WarehouseNumber > 0) {
                            //放入出库总数，如果价格库存小于出库总数量，则出库总数为入库数量加上同价格的出库总数，否则为已出库数量
                            map1.put("OutboundzNumberCount", Double.parseDouble(map1.get("formInStockNumber").toString()) - WarehouseNumber <= 0 ? Double.parseDouble(map1.get("formInStockNumber").toString()) + Double.parseDouble(setMap.get("formInStockNumber").toString()) : WarehouseNumber + Double.parseDouble(map1.get("OutboundzNumberCount").toString()));
                            //如果出库数量过大，则为0,放入当前库存
                            //当前库存
                            map1.put("NewWarehouseNumber", Double.parseDouble(map1.get("formInStockNumber").toString()) - WarehouseNumber <= 0 ? 0 + Double.parseDouble(setMap.get("NewWarehouseNumber").toString()) : Double.parseDouble(map1.get("formInStockNumber").toString()) - WarehouseNumber + Double.parseDouble(setMap.get("NewWarehouseNumber").toString()));
                            WarehouseNumber = WarehouseNumber - Double.parseDouble(map1.get("formInStockNumber").toString());
                        } else {
                            map1.put("OutboundzNumberCount", 0);
                            map1.put("NewWarehouseNumber", Double.parseDouble(map1.get("formInStockNumber").toString()));
                        }
                        setMap.put(String.valueOf(map1.get("price")), map1);

                    } else {
                        //判断已经出库数量，如果大于0则继续此操作，小于0则不进行任何操作
                        //使用总的出货量减去入库数量，如果小于0则出库总数为入库数量，大于0则为当前库存
                        if (WarehouseNumber > 0) {
                            //放入出库总数，如果价格库存小于出库总数量，则出库总数为入库数量，否则为已出库数量
                            map1.put("OutboundzNumberCount", Double.parseDouble(map1.get("formInStockNumber").toString()) - WarehouseNumber <= 0 ? Double.parseDouble(map1.get("formInStockNumber").toString()) : WarehouseNumber);
                            //当前库存
                            map1.put("NewWarehouseNumber", Double.parseDouble(map1.get("formInStockNumber").toString()) - WarehouseNumber <= 0 ? 0 : Double.parseDouble(map1.get("formInStockNumber").toString()) - WarehouseNumber);
                            WarehouseNumber = WarehouseNumber - Double.parseDouble(map1.get("formInStockNumber").toString());
                        } else {
                            map1.put("OutboundzNumberCount", 0);
                            map1.put("NewWarehouseNumber", Double.parseDouble(map1.get("formInStockNumber").toString()));

                        }
                        setMap.put(String.valueOf(map1.get("price")), map1);
                    }
                }

                for (Map.Entry<String, Object> entry : setMap.entrySet()) {
                    arr.add((Document) entry.getValue());
                }
                if (list1.size() > 1) {
                    arr.add(bo("name", "合计(" + map.get("name") + ")", "formInStockNumber", map.get("count"), "OutboundzNumberCount", map.get("WarehouseNumber"), "NewWarehouseNumber", map.get("inStockNumber")));
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return o("list", arr);
    }

    public Object one() {
        Obj item = ro(db.getCollection("article")
                .find(bo(
                        "id", $request.ss("id")
                ))
                .projection(bo("_id", 0))
                .first());

        return o(
                "article", item
        );
    }


    public boolean del() {
        return db.getCollection("article")
                .deleteOne(bo("id", $request.ss("id"))).getDeletedCount() > 0;
    }


}
